package cn.chenxinjie.hrm.service.impl;

import cn.chenxinjie.hrm.config.RabbitMQConfig;
import cn.chenxinjie.hrm.constant.CourseLevel;
import cn.chenxinjie.hrm.doc.CourseDoc;
import cn.chenxinjie.hrm.domain.Course;
import cn.chenxinjie.hrm.domain.CourseDetail;
import cn.chenxinjie.hrm.domain.CourseMarket;
import cn.chenxinjie.hrm.domain.CourseType;
import cn.chenxinjie.hrm.dto.CourseDto;
import cn.chenxinjie.hrm.feign.CourseDocFeign;
import cn.chenxinjie.hrm.mapper.CourseDetailMapper;
import cn.chenxinjie.hrm.mapper.CourseMapper;
import cn.chenxinjie.hrm.mapper.CourseMarketMapper;
import cn.chenxinjie.hrm.mapper.CourseTypeMapper;
import cn.chenxinjie.hrm.query.CourseDocQuery;
import cn.chenxinjie.hrm.service.ICourseService;
import cn.chenxinjie.hrm.util.AjaxResult;
import cn.chenxinjie.hrm.vo.UserInfoVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.LinkedList;
import java.util.List;

/**
 *  服务实现类
 *
 * @author chenxinjie
 * @since 2022-03-12
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseDetailMapper courseDetailMapper;
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private CourseDocFeign courseDocFeign;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    @Transactional
    public AjaxResult saveCourse(CourseDto courseDto) {
        // 从security上下文对象中获取登陆用户的名字
        String name = SecurityContextHolder.getContext().getAuthentication().getName();
        // 获取redis中的参数(用户所属机构信息)
        Object o = redisTemplate.opsForValue().get("authen::" + name);
        Assert.notNull(o,"用户信息为空");
        UserInfoVo vo = JSON.parseObject(JSON.toJSONString(o), UserInfoVo.class);
        // 校验参数的合法性 使用JSR303
        Course course = courseDto.getCourse();
        // 校验课程类型是否正确, 调用枚举中的方法
        CourseLevel courseLevel = CourseLevel.checkLevel(course.getGradeId(), course.getGradeName());
        Assert.notNull(courseLevel,"课程等级有误");
        // 先保存Course,返回自增主键,再保存Detail和Market
        course.setTenantName(vo.getComName());
        courseMapper.insert(course);
        CourseDetail detail = courseDto.getCourseDetail();
        detail.setId(course.getId());
        courseDetailMapper.insert(detail);
        CourseMarket market = courseDto.getCourseMarket();
        market.setId(course.getId());
        courseMarketMapper.insert(market);
        return AjaxResult.me();
    }

    @Override
    @Transactional
    public AjaxResult onLineCourse(List<Long> ids) {
        // 通过id集合查询全部的课程以及课程详情
        List<Course> courses = courseMapper.selectBatchIds(ids);
        Assert.notEmpty(courses,"不能为空!");
        List<CourseDetail> courseDetails = courseDetailMapper.selectBatchIds(ids);
        Assert.notEmpty(courseDetails,"不能为空!");
        List<CourseMarket> courseMarkets = courseMarketMapper.selectBatchIds(ids);
        Assert.notEmpty(courseMarkets,"不能为空!");

        LinkedList<CourseDoc> list = new LinkedList<>();
        for (int i = 0;i < courses.size(); i++) {
            CourseDoc courseDoc = new CourseDoc();
            Course course = courses.get(i);
            CourseDetail courseDetail = courseDetails.get(i);
            CourseMarket courseMarket = courseMarkets.get(i);
            CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());

            BeanUtils.copyProperties(course, courseDoc);
            BeanUtils.copyProperties(courseDetail, courseDoc);
            BeanUtils.copyProperties(courseMarket, courseDoc);
            courseDoc.setCourseTypeName(courseType.getName());
            list.add(courseDoc);
        };
        // 保存到ES
        courseDocFeign.addCourseDoc(list);
        // 修改数据库的状态为上架
        courseMapper.updateStatusByIds(ids);
        // 发送短信/邮件通知,放进消息队列
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME_TOPIC,"message.email",courses.get(0).getName());
        return AjaxResult.me();
    }

    @Override
    @Transactional
    public AjaxResult offLineCourse(List<Long> ids) {
        // 删除ES中的数据
        courseDocFeign.removeCourseDoc(ids);
        // 修改数据库中的课程状态为下架
        courseMapper.offLineCourse(ids);
        return AjaxResult.me();
    }

    @Override
    public AjaxResult queryCourses(CourseDocQuery query) {
        return courseDocFeign.queryCourses(query);
    }


}
